// 缓存插件
package xcache

import (
	"sync"
	"time"
)

// 是否已启动轮询任务
var crontab_lock bool = false

// 初始化轮询任务，定时清理cacheSync缓存，避免造成缓存垃圾问题
func init() {
	if !crontab_lock {
		crontab_lock = true
		go func() {
			// 每隔1小时，清空一次cache缓存
			for {
				time.Sleep(time.Hour)
				cacheSync.Clear()
			}
		}()
	}
}

// 此插件废弃之前的简单读写功能，而添加新的分级功能，概览如下：
// 1. 缓存分级：分为本地缓存、驱动缓存
// 2. 本地缓存默认使用，而不再作为无驱动时的替代方案
// 3. 驱动缓存可配置多个，会依次读取依次配置
// 4. 缓存统一有过期时间配置，不再支持不过期的缓存
// 5. 缓存分组部分不再配置独立的分组map，而是作为底层的key前缀进行配置

// 基础缓存接口实现
type CacheInteface interface {
	Name() string                                      // 缓存名称，用于区分不同缓存
	Store(name, value string, ext time.Duration) error // 存储缓存信息
	Load(name string) (string, error)                  // 读取缓存信息
	Delete(name string) error                          // 删除缓存信息
	Clear() error                                      // 清空全部缓存
	Keys() []string                                    // 获取所有缓存名称
}

// 缓存数据结构
type cacheData struct {
	Value  string // 缓存值, 字符串格式 json串行化后的值
	Expire int64  // 缓存过期时间(unix时间戳)
}

var (
	cacheSync    sync.Map        = sync.Map{}        // 缓存同步Map
	defaultExpr                  = time.Hour         // 默认过期时间
	defaultGroup                 = "default"         // 默认缓存分组前缀 key格式为：<分组>:<key名>
	cacheLevel   []CacheInteface = []CacheInteface{} // 分级缓存
)

// 设置默认缓存时长
//
//	c	默认的缓存时长(该选项会忽略0值)
func SetDefaultTime(c time.Duration) {
	if c == 0 {
		return
	}
	defaultExpr = c
}

// 设置存储驱动【追加的方式加入列表】
//
//	c	存储缓存的驱动标识
func SetInteface(c CacheInteface) {
	cacheLevel = append(cacheLevel, c)
}

// 清空分级缓存队列
func SetIntefaceClean() {
	cacheLevel = []CacheInteface{}
}

// 移除指定名称的缓存队列
//
//	name	缓存接口名称
func SetIntefaceRemove(name string) {
	ns := []CacheInteface{}
	for i := 0; i < len(cacheLevel); i++ {
		if cacheLevel[i].Name() == name {
			continue
		}
		ns = append(ns, cacheLevel[i])
	}
	cacheLevel = ns
}

// 获取缓存接口名称列表
func SetIntefaceNames() []string {
	bs := []string{}
	for _, c := range cacheLevel {
		bs = append(bs, c.Name())
	}
	return bs
}
